/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <cmsis_os2.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cmsis_os2.h"
#include "ohos_init.h"

#include "ohos_init.h"
#include "iot_demo_def.h"
#include "nativeapi_config.h"
#include "hal/hal_gpadc.h"
#include "math.h"

#include "gas_detection.h"

#define max_len 128
#define CONFIG_SENSOR_SAMPLE_CYCLE 1000
#define CN_LAMP_EVENT_ALL   (CN_SWITCH_EVENT_SETSTATUS)
#define CN_SWITCH_EVENT_SETSTATUS  (1<<0)
#define CONFIG_LOCAL_TIMEZONE            8
#define CONFIG_MAX_SEND_DATA_LEN         256
#define INIT_GAS_THRESHOLD               100
#define GAS_ADC_CHANNEL                  0

static const uint16_t GPIO02 = 2;

typedef struct {
    uint32_t GasThreshold;
    uint32_t CurrentGasCONC;
    bool wifiSts;
}ApplicationController;

char g_sendMessage[CONFIG_MAX_SEND_DATA_LEN];
ApplicationController g_appController;

#define TIMER_TICK_NUM 900

/**
 * @brief Convert miniseconds to system ticks
 * @param ms Indicates the mimiseconds to convert
 * @return Returns the corresponding ticks of specified time
 */
static uint32_t Time2Tick(uint32_t ms)
{
    uint64_t ret;
    ret = ((uint64_t)ms * osKernelGetTickFreq()) / CN_MINISECONDS_IN_SECOND;
    return (uint32_t)ret;
}

int SendDataToJs(void)
{
    char wifiStsStr[16];
    strncpy(wifiStsStr, "connected", sizeof(wifiStsStr));
    g_appController.wifiSts = true;

    memset_s(g_sendMessage, CONFIG_MAX_SEND_DATA_LEN, 0, CONFIG_MAX_SEND_DATA_LEN);
    snprintf(g_sendMessage, sizeof(g_sendMessage), "{\"CurrentGasCONC\":\"%d\", \"wifi\":\"%s\"}", 
            g_appController.CurrentGasCONC, wifiStsStr);
    int length = strlen(g_sendMessage);
    g_sendMessage[length] = 0;

    return length;
}

static int JsGetClang(const char* key, char* value)
{
    if ((key == NULL) || (value == NULL)) {
        return ERROR_CODE_PARAM;
    }
    
    int length = SendDataToJs();
    if (length > 0 && length < CONFIG_MAX_SEND_DATA_LEN) {
        strncpy(value, g_sendMessage, length);
        value[length] = 0;
    } else {
        printf(" JsGetClang .value = NULL\r\n");
    }

    return NATIVE_SUCCESS;
}

void JsSetGasThreshold(const char *value)
{
    if (value == NULL) {
        printf("error: JsSetGasThreshold value NULL\n");
        return ;
    }
    g_appController.GasThreshold = atoi(value);
    printf("value = %s, g_appController.GasThreshold:%d.\n", value, g_appController.GasThreshold);
}

static int JsSetClang(const char* key, const char* value)
{
    if ((key == NULL) || (!IsValidValue(value))) {
        return ERROR_CODE_PARAM;
    }
    printf("%s : %s--%s\n", __func__, key, value);

    if (strncmp(key, "GasThreshold", strlen("GasThreshold")) == 0) {
        JsSetGasThreshold(value);
    }
    return  NATIVE_SUCCESS;
}

int startLevel = 80;
int endLevel = 90;
int gasConc = 80;
static void MainTaskEntry(void *arg)
{
    int ret = 0;
    
    g_appController.GasThreshold = INIT_GAS_THRESHOLD;
    g_appController.CurrentGasCONC = 0;
    g_appController.wifiSts = false;
    int32_t remoteFlag = 0;
    while (1) {
        gasConc++;
        if (gasConc >= endLevel) {
            gasConc = startLevel;
        }
        g_appController.CurrentGasCONC = gasConc;
        printf("CurrentGasCONC value :%d GasThreshold: %d \n", gasConc, g_appController.GasThreshold);
        osDelay(Time2Tick(CONFIG_SENSOR_SAMPLE_CYCLE));
    }
}

int thePriority = 25;
int theStackSize = 10;
int theMultiple = 1024;
void StartMainThread(void)
{
    printf("[%s:%d]: %s\n", __FILE__, __LINE__, __func__);
    JsGetClangFuncationRegister(JsGetClang);
    JsSetClangFuncationRegister(JsSetClang);
    osThreadAttr_t attr = {0};
    attr.stack_size = theMultiple * theStackSize;
    attr.priority = thePriority;
    attr.name = "gas_detection_main_entry";
    if (osThreadNew((osThreadFunc_t)MainTaskEntry, NULL, &attr) == NULL) {
        printf("Failed to create gas_detection_main thread\r\n");
    }
}